﻿package com.agileai.miscdp.hotweb.generator.treecontent;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;

import com.agileai.miscdp.MiscdpPlugin;
import com.agileai.miscdp.hotweb.database.DBManager;
import com.agileai.miscdp.hotweb.database.SqlBuilder;
import com.agileai.miscdp.hotweb.domain.Column;
import com.agileai.miscdp.hotweb.domain.PageFormField;
import com.agileai.miscdp.hotweb.domain.treecontent.ContentTableInfo;
import com.agileai.miscdp.hotweb.domain.treecontent.TabContentTableModel;
import com.agileai.miscdp.hotweb.domain.treecontent.TreeContentFuncModel;
import com.agileai.miscdp.hotweb.domain.treecontent.TreeContentTableModel;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
/**
 * SQLMap文件代码生成器
 */
public class TACSqlMapGenerator implements Generator{
	private String sqlMapFile = null;
    private String projectName = null;
    
    private TreeContentFuncModel funcModel = null;
    
    public TACSqlMapGenerator(String projectName){
    	this.projectName = projectName;
    }
    
	public void init(TreeContentTableModel treeContentTableModel){
    	try {
	    	DBManager dbManager = DBManager.getInstance(this.projectName);
			SqlBuilder sqlBuilder = new SqlBuilder();
			
			String treeTableName = funcModel.getTreeTableName();

			HashMap<String, Column> columnMap = dbManager.getColumnMap(treeTableName);
			sqlBuilder.addColumnsMap(treeTableName,columnMap);
			
			String columnIdField = funcModel.getColumnIdField();
			String deleteTreeRecordSql = sqlBuilder.deleteSql(treeTableName, columnIdField);
			treeContentTableModel.setDeleteTreeRecordSQL(deleteTreeRecordSql);
			
			String[] colNames = MiscdpUtil.getColNames(dbManager, treeTableName);
            String insertTreeRecordSql = sqlBuilder.insertSql(treeTableName, colNames);
			treeContentTableModel.setInsertTreeRecordSQL(insertTreeRecordSql);
			
			String namespace = funcModel.getSqlNamespace();
			treeContentTableModel.setNamespace(namespace);
			
            String listSql = sqlBuilder.findAllSql(treeTableName,colNames);
			String queryChildRecordsSql = listSql + " where "+ funcModel.getColumnParentIdField() + " = #value#"
			+ " order by "+funcModel.getColumnSortField();
			treeContentTableModel.setQueryChildTreeRecordsSQL(queryChildRecordsSql);
			
            String queryCurLevelRecordsSql = sqlBuilder.queryCurLevelRecordsSql(treeTableName, colNames
            		, funcModel.getColumnIdField(),funcModel.getColumnParentIdField(), funcModel.getColumnSortField());
			treeContentTableModel.setQueryCurLevelRecordsSQL(queryCurLevelRecordsSql);
			
			String queryMaxSortIdSql = sqlBuilder.queryMaxSortIdSql(treeTableName, funcModel.getColumnSortField(),funcModel.getColumnParentIdField());
			treeContentTableModel.setQueryMaxSortIdSQL(queryMaxSortIdSql);
			
			List<String> paramFieldList = new ArrayList<String>();
			paramFieldList.add(funcModel.getColumnIdField());
			String uniqueFieldCode = funcModel.retrieveUniqueField(funcModel.getTreeEditFormFields());
			if (StringUtil.isNotNullNotEmpty(uniqueFieldCode)){
				paramFieldList.add(uniqueFieldCode);
			}
			String[] paramFields = paramFieldList.toArray(new String[0]);
			String queryTreeRecordSql = sqlBuilder.retrieveSqlByParams(colNames, treeTableName,paramFields);
			treeContentTableModel.setQueryTreeRecordSQL(queryTreeRecordSql);

			String queryTreeRecordsSql = listSql + " order by "+ funcModel.getColumnParentIdField()+","+funcModel.getColumnSortField();
			treeContentTableModel.setQueryTreeRecordsSQL(queryTreeRecordsSql);
			
            String[] primaryKeys = dbManager.getPrimaryKeys(treeTableName);
            String updateTreeRecordSql = sqlBuilder.updateSql(treeTableName, colNames, primaryKeys);
			treeContentTableModel.setUpdateTreeRecordSQL(updateTreeRecordSql);
			
			String queryPickTreeRecordsSQL = queryTreeRecordsSql;
			treeContentTableModel.setQueryPickTreeRecordsSQL(queryPickTreeRecordsSQL);
			
			List<ContentTableInfo> contentTableInfos = funcModel.getContentTableInfoList();
			for (int i=0;i < contentTableInfos.size();i++){
				ContentTableInfo contentTableInfo = contentTableInfos.get(i);
				String tabId = contentTableInfo.getTabId();
				String tabTableName = contentTableInfo.getTableName();
				HashMap<String, Column> tabColumnMap = dbManager.getColumnMap(tabTableName);
				sqlBuilder.addColumnsMap(tabTableName,tabColumnMap);
				
				String relTableName = contentTableInfo.getRelTableName();
				String tableMode = contentTableInfo.getTableMode();
				
				TabContentTableModel tabContentTableModel = new TabContentTableModel();
				tabContentTableModel.setContentTabId(contentTableInfo.getTabId());
				boolean isExistRelateTable = false;
				if (ContentTableInfo.TableMode.Many2ManyAndRel.equals(tableMode)){
					isExistRelateTable = true;
					
					HashMap<String, Column> relColumnMap = dbManager.getColumnMap(relTableName);
					sqlBuilder.addColumnsMap(relTableName,relColumnMap);
				}
				tabContentTableModel.setExistRelateTable(isExistRelateTable);
				treeContentTableModel.getContentTableInfoList().add(tabContentTableModel);
				
				String[] tabPrimaryKeys = dbManager.getPrimaryKeys(tabTableName);
				String deleteContentRecordSQL = sqlBuilder.deleteSql(tabTableName, tabPrimaryKeys);
				tabContentTableModel.setDeleteContentRecordSQL(deleteContentRecordSQL);
				
				String tabTablePrimaryKey = contentTableInfo.getPrimaryKey(this.projectName);
				String treeTablePrimaryKey = contentTableInfo.getColField();
				if (StringUtil.isNullOrEmpty(treeTablePrimaryKey)){
					treeTablePrimaryKey = primaryKeys[0];
				}
				if (isExistRelateTable){
					String[] relPrimaryKeys = dbManager.getPrimaryKeys(relTableName);
					String deleteContentRelationSQL = sqlBuilder.deleteRelationSQL(relTableName,relPrimaryKeys);
					tabContentTableModel.setDeleteContentRelationSQL(deleteContentRelationSQL);					
				}
				String findContentRecordsSQL = contentTableInfo.getQueryListSql();
				findContentRecordsSQL = MiscdpUtil.getProcessedConditionSQL(findContentRecordsSQL);
				tabContentTableModel.setFindContentRecordsSQL(findContentRecordsSQL);
				
				String[] tabColNames = MiscdpUtil.getColNames(dbManager, tabTableName);
				List<String> tabParamFieldList = new ArrayList<String>();
				tabParamFieldList.add(tabTablePrimaryKey);
				List<PageFormField> tabPageFormFieldList = funcModel.getContentEditFormFieldsMap().get(tabId);
				String tabUniqueFieldCode = funcModel.retrieveUniqueField(tabPageFormFieldList);
				if (StringUtil.isNotNullNotEmpty(tabUniqueFieldCode)){
					tabParamFieldList.add(tabUniqueFieldCode);
				}
				String[] tabParamFields = tabParamFieldList.toArray(new String[0]);
				String getContentRecordSQL = sqlBuilder.retrieveSqlByParams(tabColNames, tabTableName, tabParamFields);
				tabContentTableModel.setGetContentRecordSQL(getContentRecordSQL);
				
				String insertContentRecordSQL = sqlBuilder.insertSql(tabTableName, tabColNames);
				tabContentTableModel.setInsertContentRecordSQL(insertContentRecordSQL);
				
				if (isExistRelateTable){
					String[] relColNames = MiscdpUtil.getColNames(dbManager, relTableName);
					String insertContentRelationSQL = sqlBuilder.insertSql(relTableName, relColNames);
					tabContentTableModel.setInsertContentRelationSQL(insertContentRelationSQL);
					
					String[] relTablePrimaryKeys = dbManager.getPrimaryKeys(relTableName);
					String queryContentRelationSQL = sqlBuilder.retrieveSql(relColNames, relTableName,relTablePrimaryKeys);
					queryContentRelationSQL = MiscdpUtil.getProcessedConditionSQL(queryContentRelationSQL);
					tabContentTableModel.setQueryContentRelationSQL(queryContentRelationSQL);
					
					String updateField = treeTablePrimaryKey;
					String otherField = tabTablePrimaryKey;
					String updateContentRelationSQL = sqlBuilder.updateRelationSql(relTableName, updateField, otherField);
					tabContentTableModel.setUpdateContentRelationSQL(updateContentRelationSQL);
				}
				
				String updateContentRecordSQL = sqlBuilder.updateSql(tabTableName, tabColNames, tabPrimaryKeys);;
				tabContentTableModel.setUpdateContentRecordSQL(updateContentRecordSQL);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void generate() {
		try {
			String fileName = "template";
			String templateDir = null;
			try {
				templateDir = FileLocator.toFileURL(Platform.getBundle(MiscdpPlugin.getPluginId()).getResource(fileName)).getFile().toString();
			} catch (IOException e) {
				e.printStackTrace();
			}
			Configuration cfg = new Configuration();
			cfg.setDirectoryForTemplateLoading(new File(templateDir+"/treecontent"));
	        cfg.setObjectWrapper(new DefaultObjectWrapper());
	        Template temp = cfg.getTemplate("SqlMap.xml.ftl");
	        TreeContentTableModel treeContentTableModel = new TreeContentTableModel();
	        treeContentTableModel.setManageTree(funcModel.isManageTree());
	        this.init(treeContentTableModel);
	        Map root = new HashMap();
	        root.put("table",treeContentTableModel);
	        FileWriter out = new FileWriter(new File(this.sqlMapFile));
	        temp.process(root, out);
	        out.flush();			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public void setFuncModel(TreeContentFuncModel funcModel) {
		this.funcModel = funcModel;
	}

	public void setSqlMapFile(String sqlMapFile) {
		this.sqlMapFile = sqlMapFile;
	}
	
	
}
